﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace VirtualOperator
{
    public enum TabPageEnum { PROPERTY, VIRTUAL_NETWORK, ADD_VIRTUAL_LINK, ADD_SINK, ADD_SOURCE, SETUP, TEARDOWN, SAVE }

    public partial class VirtualNetworkTools : Form
    {
        private class GListViewItem : ListViewItem
        {
            public TabPage Tab { get; private set; }

            public GListViewItem(string text, string imageKey, TabPage tab)
            {
                this.Text = text;
                this.ImageKey = imageKey;
                this.Tab = tab;

            }
        }
        private class FilePath
        {

            public string FullFilepath { get; private set; }

            public FilePath(string filepath)
            { this.FullFilepath = filepath; }



            public override string ToString()
            {
                return Path.GetFileName(FullFilepath);
            }
        }
        private VirtualNetworkOperator vno;
        public VirtualNetworkTools(VirtualNetworkOperator vno, TabPageEnum page)
        {
            InitializeComponent();
            this.vno = vno;
            label18.Hide();
            label20.Hide();
            label21.Hide();
            errorRateNumericUpDown.Hide();
            matrixDelayNumericUpDown.Hide();
            linkDelayNumericUpDown.Hide();
            this.LoadImages();

            menuListView.Items.Add(new GListViewItem("VNO", "tools.png", tabControl.TabPages["VNO"]));
            menuListView.Items.Add(new GListViewItem("Add new virtual network", "network.png", tabControl.TabPages["VirtualNetworks"]));
            menuListView.Items.Add(new GListViewItem("Add virtual link", "addvirtuallink.png", tabControl.TabPages["AddVL"]));
            menuListView.Items.Add(new GListViewItem("Add sink", "addsink.png", tabControl.TabPages["AddSink"]));
            menuListView.Items.Add(new GListViewItem("Add source", "addsource.png", tabControl.TabPages["AddSource"]));
            menuListView.Items.Add(new GListViewItem("Setup connection", "setup.png", tabControl.TabPages["SetupConn"]));
            menuListView.Items.Add(new GListViewItem("Teardown connection", "teardown.png", tabControl.TabPages["TeardownConn"]));
            menuListView.Items.Add(new GListViewItem("Teardown connection", "save.png", tabControl.TabPages["LoadSaveVNTabPage"]));


            /*
            menuListBox.ImageList = il;
            menuListBox.Items.Add(new GListBoxItem(tabControl.TabPages["VNO"], 4));
            menuListBox.Items.Add(new GListBoxItem(tabControl.TabPages["VirtualNetworks"], 3));
            menuListBox.Items.Add(new GListBoxItem(tabControl.TabPages["AddVL"], 0));
            menuListBox.Items.Add(new GListBoxItem(tabControl.TabPages["AddSink"], 1));
            menuListBox.Items.Add(new GListBoxItem(tabControl.TabPages["AddSource"], 2));
            menuListBox.Items.Add(new GListBoxItem(tabControl.TabPages["SetupConn"], 5));
            menuListBox.Items.Add(new GListBoxItem(tabControl.TabPages["TeardownConn"], 6));
            menuListBox.Items.Add(new GListBoxItem(tabControl.TabPages["LoadSaveVNTabPage"], 7));
             */



            if (vno.Communicator.Connected)
                labelStatus.Text = "on";
            else
                labelStatus.Text = "off";

            capacityDomainUpDown.Items.Add(1);
            capacityDomainUpDown.Items.Add(2);
            capacityDomainUpDown.Items.Add(4);
            capacityDomainUpDown.Items.Add(8);
            capacityDomainUpDown.Items.Add(16);
            capacityDomainUpDown.Items.Add(32);
            capacityDomainUpDown.Items.Add(64);
            capacityDomainUpDown.SelectedIndex = 0;

            capacitySetupDomainUpDown.Items.Add(1);
            capacitySetupDomainUpDown.Items.Add(2);
            capacitySetupDomainUpDown.Items.Add(4);
            capacitySetupDomainUpDown.Items.Add(8);
            capacitySetupDomainUpDown.Items.Add(16);
            capacitySetupDomainUpDown.Items.Add(32);
            capacitySetupDomainUpDown.Items.Add(64);
            capacitySetupDomainUpDown.Items.Add(1);
            capacitySetupDomainUpDown.SelectedIndex = 0;


                foreach (VirtualNetwork.Matrix m in vno.BindingAccessibleMatrixes)
                {
                    SourceMatrixComboBox.Items.Add(m);
                    TargetMatrixComboBox.Items.Add(m);
                }

            if (vno.CurrentVirtualNetwork != null)
            {
                toComboBox.DataSource = vno.CurrentVirtualNetwork.Sinks;
                fromComboBox.DataSource = vno.CurrentVirtualNetwork.Sources;

                addSinkComboBox.DataSource = vno.CurrentVirtualNetwork.Matrixes;
                addSourceComboBox.DataSource = vno.CurrentVirtualNetwork.Matrixes;
                
                connectionsListBox.DataSource = vno.CurrentVirtualNetwork.UserConnections;
                nwTTPListBox.DataSource = vno.CurrentVirtualNetwork.Users;
                virtualLinkListBox.DataSource = vno.CurrentVirtualNetwork.Links;
            }

                virtualNetworkListBox.DataSource = vno.BindingVirtualNetworks;

            this.ReadVirtualNetworkFilePaths();
            this.SelectTable(page);

        }
        private void LoadImages()
        {
            string outputDir = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath);

            DirectoryInfo dir = new DirectoryInfo(outputDir + "\\Pictures");

            foreach (FileInfo file in dir.GetFiles())
            {
                try
                {
                    if (file.Extension == ".png")
                        this.imageList.Images.Add(file.Name, Image.FromFile(file.FullName));
                }
                catch
                {

                }
            }

            this.menuListView.View = View.Tile;
            this.imageList.ImageSize = new Size(40, 40);
            this.menuListView.LargeImageList = this.imageList;
        }

        private void ReadVirtualNetworkFilePaths()
        {
            string outputDir = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath);

            DirectoryInfo dir = new DirectoryInfo(outputDir + "\\Save");
            filesToLoad.Items.Clear();
            foreach (FileInfo file in dir.GetFiles())
            {
                try
                {
                    if (file.Extension == ".xml")
                        filesToLoad.Items.Add(file);
                }
                catch
                {

                }
            }

        }


        private void SelectTable(TabPageEnum page)
        {
            switch (page)
            {
                case TabPageEnum.PROPERTY:
                    tabControl.SelectedIndex = 0;
                    //menuListBox.SelectedIndex = 0;
                    break;
                case TabPageEnum.VIRTUAL_NETWORK:
                    tabControl.SelectedIndex = 1;
                    //menuListBox.SelectedIndex = 1;
                    break;
                case TabPageEnum.ADD_VIRTUAL_LINK:
                    tabControl.SelectedIndex = 2;
                    // menuListBox.SelectedIndex = 2;
                    break;
                case TabPageEnum.ADD_SINK:
                    tabControl.SelectedIndex = 3;
                    // menuListBox.SelectedIndex = 3;
                    break;
                case TabPageEnum.ADD_SOURCE:
                    tabControl.SelectedIndex = 4;
                    //menuListBox.SelectedIndex = 4;
                    break;
                case TabPageEnum.SETUP:
                    tabControl.SelectedIndex = 5;
                    //menuListBox.SelectedIndex = 5;
                    break;
                case TabPageEnum.TEARDOWN:
                    tabControl.SelectedIndex = 6;
                    // menuListBox.SelectedIndex = 6;
                    break;
                case TabPageEnum.SAVE:
                    tabControl.SelectedIndex = 7;
                    // menuListBox.SelectedIndex = 6;
                    break;
                default:
                    tabControl.SelectedIndex = 0;
                    // menuListBox.SelectedIndex = 0;
                    break;

            }


        }


        private void CloseButton_Click(object sender, EventArgs e)
        {
            this.Close();
        }



        private void LoadConfigButton_Click(object sender, EventArgs e)
        {
            VOConfig config = VOConfig.fopen("VNOconfig.xml");
            IDTextBox.Text = config.Id.ToString();
            PortTextBox.Text = config.Port.ToString();
            AddresTextBox.Text = config.IPAddress;
            VNONameTextBox.Text = config.Name;

        }

        private void SaveConfigButton_Click(object sender, EventArgs e)
        {
            VOConfig config = new VOConfig();
            try
            {
                config.Id = Int32.Parse(IDTextBox.Text);
                config.Port = Int32.Parse(PortTextBox.Text);
                config.IPAddress = AddresTextBox.Text;
                config.Name = VNONameTextBox.Text;
                config.save("VNOconfig.xml");
            }
            catch (FormatException) { MessageBox.Show("Unable to do that"); }
        }

        private void ConnectButton_Click(object sender, EventArgs e)
        {
            try
            {
                bool result = vno.ConnectToPicsNC();
                if (result)
                {
                    labelStatus.Text = "on";
                    vno.GetMatrixes();
                    foreach (VirtualNetwork.Matrix node in vno.AccessibleMatrixes.Values.ToList())
                    {
                        SourceMatrixComboBox.Items.Add(node);
                        TargetMatrixComboBox.Items.Add(node);

                    }
                }
                else
                    labelStatus.Text = "off";
            }
            catch (Exception) { MessageBox.Show("You are not connected with PicsNC"); }
        }

        private void CreateNetworkLinkButton_Click(object sender, EventArgs e)
        {
            try
            {
                if (SourceMatrixComboBox.SelectedItem == TargetMatrixComboBox.SelectedItem)
                {
                    MessageBox.Show("You cant make a path through one matrix");
                    return;
                }
                int capacity = Int32.Parse(capacityDomainUpDown.Text);
                int maxDelay = Int32.Parse(linkDelayTextBox.Text);
                float linkErrorrate = float.Parse(LinkErrorRateTextBox.Text);
                //int matrxDelay = Int32.Parse(matrixDelayTextBox.Text);
                VirtualNetwork.Matrix source = (VirtualNetwork.Matrix)SourceMatrixComboBox.SelectedItem;
                VirtualNetwork.Matrix target = (VirtualNetwork.Matrix)TargetMatrixComboBox.SelectedItem;
                VirtualNetwork.Link link = null; ;
                if ((link = vno.AddVirtualLink(source, target, maxDelay, linkErrorrate, capacity)) != null)
                {
                    addSinkComboBox.Items.Add(link.Target); 
                    addSourceComboBox.Items.Add(link.Source);

                }
            }
            catch (FormatException) { MessageBox.Show("format failer"); }
            catch (VNONotConnected) { MessageBox.Show("You are not connected with PicsNC"); }
            catch (NullReferenceException) { MessageBox.Show("You dont choose any wirtual network"); }

        }

        private void AddSource_Click(object sender, EventArgs e)
        {
            label18.Hide();
            label20.Hide();
            label21.Hide();
            errorRateNumericUpDown.Hide();
            matrixDelayNumericUpDown.Hide();
            linkDelayNumericUpDown.Hide();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (virtualnetworkNameTextBox.Text == "")
            {
                MessageBox.Show("You need to put name of the new virtuala newtork first.");
                return;
            }
            int id;
            vno.AddVirtualNetwork(virtualnetworkNameTextBox.Text, (int)matrixDelayNumericUpDown.Value, (int)linkDelayNumericUpDown.Value, (int)errorRateNumericUpDown.Value);
    


        }

        private void button1_Click(object sender, EventArgs e)
        {
            
            linkDelayTextBox.Text = "10";
            LinkErrorRateTextBox.Text = "0,1";

        }

        private void removeButton_Click(object sender, EventArgs e)
        {
            var topology = (VirtualNetwork)virtualNetworkListBox.SelectedItem;
            if (topology == null)
            {
                MessageBox.Show("You didnt choose any virtual network");
                return;
            }
            virtualNetworkListBox.Items.Remove(topology);
            vno.RemoveVirtualNetwork(topology.ID);
        }

        private void addSinkButton_Click(object sender, EventArgs e)
        {

            if (addSinkComboBox.SelectedItem == null)
            {
                MessageBox.Show("You need to select matrix to add firts");
                return;
            }
            VirtualNetwork.Matrix node = (VirtualNetwork.Matrix)addSinkComboBox.SelectedItem;

            if (vno.AddSink(node))
            {
                toComboBox.DataSource = vno.CurrentVirtualNetwork.Sinks;
                MessageBox.Show("Sink was sucessfully added");
            }
        }

        private void addSourceButton_Click(object sender, EventArgs e)
        {
            if (addSourceComboBox.SelectedItem == null)
            {
                fromComboBox.DataSource = vno.CurrentVirtualNetwork.Sources;
                MessageBox.Show("You need to select matrix to add firts");
                return;
            }
            VirtualNetwork.Matrix node = (VirtualNetwork.Matrix)addSourceComboBox.SelectedItem;

            if (vno.AddSource(node))
            {
                fromComboBox.DataSource = vno.CurrentVirtualNetwork.Sources;
                MessageBox.Show("Source was sucessfully added");
            }
        }

        private void setupConnectionButton_Click(object sender, EventArgs e)
        {
            int capacity = Int32.Parse(capacitySetupDomainUpDown.SelectedItem.ToString());
            NwTTP trg = toComboBox.SelectedValue as NwTTP;
            NwTTP src = fromComboBox.SelectedValue as NwTTP;
            UserConnection uc = null;
            if ((uc = vno.CurrentVirtualNetwork.SetupConnection(src, trg, capacity)) != null)
            {
                MessageBox.Show("connection added");
                vno.CurrentVirtualNetwork.CC.BeginCall(uc);
            }
        }

        private void advanceButton_Click(object sender, EventArgs e)
        {
            label18.Show();
            label20.Show();
            label21.Show();
            errorRateNumericUpDown.Show();
            matrixDelayNumericUpDown.Show();
            linkDelayNumericUpDown.Show();
        }

        private void saveCurrentVN_Click(object sender, EventArgs e)
        {
            try
            {
                vno.SaveVirtualNetwork();
                this.ReadVirtualNetworkFilePaths();
            }
            catch (NullReferenceException) { MessageBox.Show("You didnt select any virtual network!"); }
            catch (VNONotConnected) { MessageBox.Show("You are not connected with PicsNC!"); }
            catch (Exception) { MessageBox.Show("You cant open the file!"); }
        }

        private void loadVN_Click(object sender, EventArgs e)
        {
            try
            {
                string filepath = (filesToLoad.SelectedItem as FileInfo).FullName;
                vno.LoadVirtualNetwork(filepath);
            }
            catch (NullReferenceException) { MessageBox.Show("You didnt select any virtual network!"); }
            catch (VNONotConnected) { MessageBox.Show("You are not connected with PicsNC!"); }
            catch (WrongNetworkTopology) { MessageBox.Show("Transport layer is different from transport layaer that this file is destined!"); }
            catch (VirtualNetworkExist) { MessageBox.Show("Current network already exist"); }
            catch (Exception) { MessageBox.Show("You cant open the file!"); }
        }

        private void menuListView_MouseClick(object sender, MouseEventArgs e)
        {
            GListViewItem item = menuListView.SelectedItems[0] as GListViewItem;
            tabControl.SelectedTab = (TabPage)item.Tab;
        }

        private void teardownButton_Click(object sender, EventArgs e)
        {
            var uc = connectionsListBox.SelectedValue as UserConnection;
            vno.CurrentVirtualNetwork.TeardownConnection(uc.ID);
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            var link = connectionsListBox.SelectedValue as VirtualNetwork.Link;
            vno.CurrentVirtualNetwork.RemoveLink(link);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            var nwttp = nwTTPListBox.SelectedValue as NwTTP;
            vno.CurrentVirtualNetwork.RemoveNwTTP(nwttp);
        }

        private void label18_Click(object sender, EventArgs e)
        {

        }

        private void label20_Click(object sender, EventArgs e)
        {

        }


    }
}
